<h2>Why is this an issue?</h2>
<p><code>Map</code> is an object that maps keys to values. A map cannot contain duplicate keys, which means each key can map to at most one value.</p>
<p>When both the key and the value are needed, it is more efficient to iterate the <code>entrySet()</code>, which will give access to both instead of
iterating over the <code>keySet()</code> and then getting the value.</p>
<p>If the <code>entrySet()</code> method is not iterated when both the key and value are needed, it can lead to unnecessary lookups. This is because
each lookup requires two operations: one to retrieve the key and another to retrieve the value. By iterating the <code>entrySet()</code> method, the
key-value pair can be retrieved in a single operation, which can improve performance.</p>
<h3>Noncompliant code example</h3>
<pre data-diff-id="1" data-diff-type="noncompliant">
public void doSomethingWithMap(Map&lt;String,Object&gt; map) {
  for (String key : map.keySet()) {  // Noncompliant; for each key the value is retrieved
    Object value = map.get(key);
    // ...
  }
}
</pre>
<h3>Compliant solution</h3>
<pre data-diff-id="1" data-diff-type="compliant">
public void doSomethingWithMap(Map&lt;String,Object&gt; map) {
  for (Map.Entry&lt;String,Object&gt; entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
    // ...
  }
}
</pre>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> <a href="https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/util/Map.html">Oracle SE 20 - Map</a> </li>
</ul>
<h3>Articles &amp; blog posts</h3>
<ul>
  <li> <a href="https://www.baeldung.com/java-map-entries-methods">Baeldung - Java Map methods</a> </li>
</ul>
<h3>Benchmarks</h3>
<table>
  <colgroup>
    <col style="width: 20%;">
    <col style="width: 20%;">
    <col style="width: 20%;">
    <col style="width: 20%;">
    <col style="width: 20%;">
  </colgroup>
  <thead>
    <tr>
      <th>Method</th>
      <th>size</th>
      <th>Runtime</th>
      <th>Average time</th>
      <th>Error margin</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><p>usingEntrySet</p></td>
      <td><p>10</p></td>
      <td><p>Temurin 21</p></td>
      <td><p>27.48 ns/op</p></td>
      <td><p>±6.22 ns/op</p></td>
    </tr>
    <tr>
      <td><p>usingEntrySet</p></td>
      <td><p>1000</p></td>
      <td><p>Temurin 21</p></td>
      <td><p>2480.26 ns/op</p></td>
      <td><p>±899.05 ns/op</p></td>
    </tr>
    <tr>
      <td><p>usingEntrySet</p></td>
      <td><p>10000</p></td>
      <td><p>Temurin 21</p></td>
      <td><p>22745.78 ns/op</p></td>
      <td><p>±10505.46 ns/op</p></td>
    </tr>
    <tr>
      <td><p>usingKeySet</p></td>
      <td><p>10</p></td>
      <td><p>Temurin 21</p></td>
      <td><p>49.70 ns/op</p></td>
      <td><p>±3.78 ns/op</p></td>
    </tr>
    <tr>
      <td><p>usingKeySet</p></td>
      <td><p>1000</p></td>
      <td><p>Temurin 21</p></td>
      <td><p>5061.54 ns/op</p></td>
      <td><p>±2056.60 ns/op</p></td>
    </tr>
    <tr>
      <td><p>usingKeySet</p></td>
      <td><p>10000</p></td>
      <td><p>Temurin 21</p></td>
      <td><p>46689.04 ns/op</p></td>
      <td><p>±14509.97 ns/op</p></td>
    </tr>
  </tbody>
</table>
<p><strong>Benchmarking code</strong></p>
<p>The results were generated by running the following snippet with <a href="https://github.com/openjdk/jmh">JMH</a>.</p>
<pre>
@BenchmarkMode({Mode.AverageTime})
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
public class S2864 {
  @Param({"10", "1000", "10000"})
  int size;

  Map&lt;Integer,Integer&gt; map;

  @Setup(Level.Trial)
  public void setup() {
    Random random = new Random();
    map = new HashMap&lt;&gt;();
    for (int i = 0; i &lt; size; i++) {
      map.put(i, random.nextInt());
    }
  }

  @Benchmark
  public int usingKeySet() {
    int sumKeysValues = 0;
    for (Integer key : map.keySet()) {
      sumKeysValues += key + map.get(key);
    }
    return sumKeysValues;
  }

  @Benchmark
  public int usingEntrySet() {
    int sumKeysValues = 0;
    for (Map.Entry&lt;Integer, Integer&gt; entry : map.entrySet()) {
      sumKeysValues += entry.getKey() + entry.getValue();
    }
    return sumKeysValues;
  }
}
</pre>

